Package bg.smoc.web.servlet.judge

Source Code of bg.smoc.web.servlet.judge.ResultsTableGenerator

package bg.smoc.web.servlet.judge;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;

import bg.smoc.model.AccumulatedGrade;
import bg.smoc.model.Contest;
import bg.smoc.model.Person;
import bg.smoc.model.Task;
import bg.smoc.model.UserAccount;
import bg.smoc.model.UserContestData;
import bg.smoc.model.manager.GraderManager;
import bg.smoc.model.web.ResultsCell;
import bg.smoc.model.web.ResultsRow;
import bg.smoc.model.web.ResultsStyle;
import bg.smoc.model.web.ResultsTable;

public class ResultsTableGenerator {

    /**
     * Set externally.
     */
    private boolean includeTestGroupResults;

    /**
     * Set externally.
     */
    private List<Contest> selectedContests;

    /**
     * Set externally.
     */
    private Vector<UserAccount> userAccounts;

    /**
     * Set externally.
     */
    private GraderManager graderManager;

    /**
     * Set externally.
     */
    private Vector<Person> persons;

    /**
     * Returned to caller.
     */
    private ResultsTable resultsTable;

    /**
     * Returned to caller.
     */
    private String autoReloadLink;

    /**
     * Returned to caller.
     */
    private String detailsLink;

    /**
     * Internal usage only.
     */
    private Hashtable<String, Hashtable<String, UserContestData>> reportData;

    /**
     * Internal usage only.
     */
    private List<Person> personsInReport;

    /**
     * Internal usage only.
     */
    private ArrayList<String[]> personLogins;

    public boolean isIncludeTestGroupResults() {
        return includeTestGroupResults;
    }

    public void setIncludeTestGroupResults(boolean includeTestGroupResults) {
        this.includeTestGroupResults = includeTestGroupResults;
    }

    public List<Contest> getSelectedContests() {
        return selectedContests;
    }

    public GraderManager getGraderManager() {
        return graderManager;
    }

    public void setGraderManager(GraderManager graderManager) {
        this.graderManager = graderManager;
    }

    public void setSelectedContests(List<Contest> selectedContests) {
        this.selectedContests = selectedContests;
    }

    public Vector<UserAccount> getUserAccounts() {
        return userAccounts;
    }

    public void setUserAccounts(Vector<UserAccount> userAccounts) {
        this.userAccounts = userAccounts;
    }

    public String getAutoReloadLink() {
        return autoReloadLink;
    }

    public String getDetailsLink() {
        return detailsLink;
    }

    public Vector<Person> getPersons() {
        return persons;
    }

    public void setPersons(Vector<Person> persons) {
        this.persons = persons;
    }

    public void createReportData() {
        if (includeTestGroupResults) {
            detailsLink = getBaseLink();
            autoReloadLink = getBaseLink() + "&detail=group";
        } else {
            detailsLink = getBaseLink() + "&detail=group";
            autoReloadLink = getBaseLink();
        }

        initializeReportData();
        initializePersonMap();
        resultsTable = new ResultsTable();
        loadHeaderList();
        loadTableData();
    }

    private void loadHeaderList() {
        ResultsRow headerRow = resultsTable.addHeader();
        ResultsStyle styleHeader = new ResultsStyle();
        styleHeader.setBold(true);

        headerRow.addCell("Rank", styleHeader);
        headerRow.addCell("Names", styleHeader);
        headerRow.addCell("Team", styleHeader);
        for (Contest contest : selectedContests) {
            headerRow.addCell("Login", styleHeader);
            for (Task task : contest.getTasks()) {
                if (includeTestGroupResults) {
                    for (int i = 0; i < task.getTestGroups().size(); ++i) {
                        headerRow.addCell(Integer.toString(i + 1), styleHeader);
                    }
                }
                headerRow.addCell(task.getName(), styleHeader);
            }
            headerRow.addCell(needsGrandTotal() ? contest.getShortName() : "Total", styleHeader);
        }
        if (needsGrandTotal()) {
            headerRow.addCell("Grand total", styleHeader);
        }
    }

    private boolean needsGrandTotal() {
        return selectedContests.size() > 1;
    }

    private void initializeReportData() {
        reportData = new Hashtable<String, Hashtable<String, UserContestData>>();
        for (Contest contest : selectedContests) {
            reportData.put(contest.getId(), reportForContest(contest));
        }
    }

    private Hashtable<String, UserContestData> reportForContest(Contest contest) {
        if (contest == null || contest.getId() == null)
            return null;
        Hashtable<String, UserContestData> result = new Hashtable<String, UserContestData>();

        for (UserAccount user : userAccounts) {
            if (!user.getContestIds().contains(contest.getId()))
                continue;
            result.put(user.getLogin(), reportForUser(contest, user.getLogin()));
        }

        return result;
    }

    private UserContestData reportForUser(Contest contest, String login) {
        BigDecimal totalPoints = BigDecimal.ZERO;

        ResultsRow row = new ResultsRow();
        row.addCell(login);
        for (Task task : contest.getTasks()) {
            AccumulatedGrade testResults = graderManager.getResult(contest.getId(), login, task);
            if (includeTestGroupResults) {
                for (int i = 0; i < testResults.getTestGroups().size(); ++i) {
                    ResultsCell cell = new ResultsCell("-");
                    if (testResults != null) {
                        cell.setValue(testResults.getTestGroups().get(i));
                        if (task.getType() == Task.PROBLEM_TYPE_OUTPUT) {
                            cell.setHref("?contestId="
                                    + contest.getId()
                                    + "&login="
                                    + login
                                    + "&taskId="
                                    + task.getNameForTest(i + 1));
                        }
                    }
                    row.addCell(cell);
                }
            }
            if (testResults != null) {
                totalPoints = totalPoints.add(new BigDecimal(testResults.getTotal()));
            }
            ResultsCell cell = new ResultsCell(testResults != null ? testResults.getTotal()
                    : BigDecimal.ZERO.toString());
            if (task.getType() != Task.PROBLEM_TYPE_OUTPUT) {
                cell.setHref("?contestId="
                        + contest.getId()
                        + "&login="
                        + login
                        + "&taskId="
                        + task.getName());
            }
            row.addCell(cell);
        }
        row.addCell(totalPoints.toString());

        UserContestData data = new UserContestData();
        data.setData(row);
        data.setTotalPoints(totalPoints);
        return data;
    }

    private String getBaseLink() {
        StringBuffer result = new StringBuffer("");
        for (Contest contest : selectedContests) {
            if (result.length() > 0) {
                result.append("&");
            }
            result.append(contest.getId());
            result.append("=on");
        }
        return result.toString();
    }

    public ResultsTable getResultsTable() {
        return resultsTable;
    }

    private void initializePersonMap() {
        personsInReport = new ArrayList<Person>();
        personLogins = new ArrayList<String[]>();

        Map<String, Set<String>> personsInContest = new HashMap<String, Set<String>>();
        for (Contest contest : selectedContests) {
            personsInContest.put(contest.getId(), new TreeSet<String>(reportData.get(contest
                    .getId()).keySet()));
        }

        for (Person person : persons) {
            if (person.getLogins() == null || person.getLogins().size() == 0) {
                continue;
            }

            String[] logins = new String[selectedContests.size()];
            boolean include = false;
            int index = 0;
            for (Contest contest : selectedContests) {
                for (String login : person.getLogins()) {
                    if (personsInContest.get(contest.getId()).remove(login)) {
                        logins[index] = login;
                        include = true;
                        break;
                    }
                }
                index++;
            }

            if (include) {
                personsInReport.add(person);
                personLogins.add(logins);
            }
        }

        for (Contest contest : selectedContests) {
            for (String login : personsInContest.get(contest.getId())) {
                personsInReport.add(Person.getBlankPerson(login));
                String[] logins = new String[selectedContests.size()];
                int index = 0;
                for (Contest rowContest : selectedContests) {
                    logins[index] = ((rowContest == contest) ? login : null);
                    index++;
                }
                personLogins.add(logins);
            }
        }
    }

    private ResultsRow getBlankContestData(Contest contest) {
        ResultsRow row = new ResultsRow();
        row.addCell("-");
        for (Task task : contest.getTasks()) {
            if (includeTestGroupResults) {
                for (int i = 0; i < task.getTestGroups().size(); ++i) {
                    row.addCell("-");
                }
            }
            row.addCell("-");
        }
        row.addCell("0");
        return row;
    }

    private void loadTableData() {
        for (int index = 0; index < personsInReport.size(); ++index) {
            Person person = personsInReport.get(index);
            String[] logins = personLogins.get(index);

            BigDecimal grandTotalPoints = BigDecimal.ZERO;
            ResultsRow row = new ResultsRow();
            row.addCell(person.getNames());
            row.addCell(person.getTown());
            int secondary = 0;
            for (Contest contest : selectedContests) {
                String login = logins[secondary++];
                Hashtable<String, UserContestData> contestData = null;
                UserContestData userContestData = null;
                if (login != null) {
                    contestData = reportData.get(contest.getId());
                    if (contestData != null) {
                        userContestData = contestData.get(login);
                    }
                }
                if (userContestData == null) {
                    row.append(getBlankContestData(contest));
                } else {
                    row.append(userContestData.getData());
                    grandTotalPoints = grandTotalPoints.add(userContestData.getTotalPoints());
                }
            }
            if (needsGrandTotal()) {
                row.addCell(grandTotalPoints.toString());
            }
            resultsTable.appendRow(row);
        }
        sortTableRows();
    }

    private void sortTableRows() {
        Vector<ResultsRow> newRows = new Vector<ResultsRow>();
        Vector<ResultsRow> tableRows = resultsTable.getRows();
        boolean[] used = new boolean[tableRows.size()];
        for (int i = 0; i < tableRows.size(); ++i) {
            used[i] = false;
        }
        for (int i = 0; i < tableRows.size(); ++i) {
            int index = -1;
            BigDecimal max = BigDecimal.ZERO;
            for (int j = 0; j < tableRows.size(); ++j) {
                BigDecimal points = new BigDecimal(tableRows.get(j).getCells().lastElement()
                        .getValue());
                if (!used[j] && max.compareTo(points) <= 0) {
                    max = points;
                    index = j;
                }
            }
            used[index] = true;
            newRows.add(tableRows.get(index));
        }

        tableRows = newRows;
        newRows = new Vector<ResultsRow>();

        for (int i = 0; i < tableRows.size(); ++i) {
            BigDecimal points = new BigDecimal(tableRows.get(i).getCells().lastElement().getValue());

            int count = 1;
            for (; i + count < tableRows.size(); ++count) {
                if (points.compareTo(new BigDecimal(tableRows.get(i + count).getCells()
                        .lastElement().getValue())) != 0)
                    break;
            }

            for (int j = 0; j < count; ++j) {
                ResultsRow row = new ResultsRow();
                if (count > 1) {
                    row.addCell(Integer.toString(i + 1) + "-" + Integer.toString(i + count));
                } else {
                    row.addCell(Integer.toString(i + 1));
                }
                row.append(tableRows.get(i + j));
                newRows.add(row);
            }

            i += count - 1;
        }
        resultsTable.setRows(newRows);
    }

}
TOP

Related Classes of bg.smoc.web.servlet.judge.ResultsTableGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.